import clang.cindex
import os
import re
import argparse
import json

from utils import is_system_function_declaration, LLVM_LIBRARY_PATH, clang_options, generate_header_path

def filter_preprocessor_directives(content):
    """
    过滤掉指定的预处理指令。
    """
    # 移除 #ifndef, #define, #endif
    content = re.sub(r'#ifndef.*?#define.*?#endif', '', content, flags=re.DOTALL)

    # 移除单独的 #ifdef 和 #endif
    content = re.sub(r'#ifdef.*?#endif', '', content, flags=re.DOTALL)

    # 移除 extern "C" 块
    content = re.sub(r'extern\s*"C"\s*{.*?}', '', content, flags=re.DOTALL)

    # 移除多余的空行
    content = re.sub(r'\n\s*\n', '\n', content)

    return content

def get_rust_symbols(json_path):
    rust_symbol = dict()
    with open(json_path, "r") as jfile:
        data = json.load(jfile)
        if "Rust" in data and "symbol_table" in data["Rust"]:
            rust_symbol = data["Rust"]["symbol_table"]
    
    return rust_symbol

def extract_dependent_rust_interface(header_path, include_dirs):
    if not clang.cindex.Config.loaded:
        # 配置libclang的路径，请根据你的实际路径进行配置
        clang.cindex.Config.set_library_path(LLVM_LIBRARY_PATH)
    index = clang.cindex.Index.create()
    translation_unit = index.parse(header_path, args=generate_header_path(include_dirs), options=clang_options)
    with open(header_path, "r") as h_file:
        header_full_code = h_file.readlines()

    # 提取包含的头文件信息
    with open(header_path, 'r') as file:
        header_code = file.read()
        header_code = filter_preprocessor_directives(header_code)
        pro_include_pattern = re.compile(r'#include\s+"(.+\.h)"')
        pro_includes = pro_include_pattern.findall(header_code)

        rust_interface = dict()
        pro_include_files = list()

        for pro_include in pro_includes:
            header_content = pro_include.split('.h')[0]
            pro_src = "Intermediate-Result"
            pro_test = "Intermediate-Result-test"
            json_file = header_content + "_output.json"
            pro_src_path = os.path.join(pro_src, json_file)
            pro_test_path = os.path.join(pro_test, json_file)
            rust_symbol = dict()
            if os.path.exists(pro_src_path):
                rust_symbol = get_rust_symbols(pro_src_path)
                pro_include_files.append(pro_src_path)
            elif os.path.exists(pro_test_path):
                rust_symbol = get_rust_symbols(pro_test_path)
                pro_include_files.append(pro_test_path)
            else:
                pass
            if len(rust_symbol) > 0:
                rust_interface.update(rust_symbol)
   
    return rust_interface, pro_include_files

# if __name__ == "__main__":
#     parser = argparse.ArgumentParser(description="Parse .h file and extract global symbol content.")
#     parser.add_argument('header_file', type=str, help="Path to the hearder file (.h)")

#     args = parser.parse_args()
#     from utils import system_header_paths
#     extract_dependent_rust_interface(args.header_file, system_header_paths)


def test_rust_interface():
    import sys
    
    # 设置测试头文件路径
    test_header_file = "test_files/include/test.h"
    
    # 模拟命令行参数
    sys.argv = [
        "extract_rust_interface.py",
        test_header_file
    ]
    
    # 创建必要的输出目录
    os.makedirs("Intermediate-Result", exist_ok=True)
    
    # 创建示例JSON输出文件
    sample_json = {
        "Rust": {
            "symbol_table": {
                "Point": {
                    "type": "struct",
                    "fields": {
                        "x": "i32",
                        "y": "i32"
                    }
                },
                "move_point": {
                    "type": "function",
                    "args": ["*mut Point", "i32", "i32"],
                    "return_type": "void"
                }
            }
        }
    }
    
    # 写入示例JSON文件
    with open("Intermediate-Result/test_output.json", "w") as f:
        json.dump(sample_json, f, indent=4)
    
    # 调用原main函数的逻辑
    parser = argparse.ArgumentParser(description="Parse .h file and extract global symbol content.")
    parser.add_argument('header_file', type=str, help="Path to the header file (.h)")
    
    args = parser.parse_args()
    from utils import system_header_paths
    rust_interface, include_files = extract_dependent_rust_interface(args.header_file, system_header_paths)
    
    # 打印结果
    print("提取的Rust接口:")
    print(json.dumps(rust_interface, indent=4))
    print("\n包含的文件:")
    for file in include_files:
        print(file)

if __name__ == "__main__":
    test_rust_interface()